const aGoods = {
  pic: ".",
  title: "..",
  desc: `...`,
  sellNumber: 1,
  favorRate: 2,
  price: 3,
};

class UIGoods {
  constructor(g) {
    g = { ...g };
    // Object.freeze: 完全不可变：冻结后的对象，其现有属性值不可修改（包括数据属性和访问器属性）
    Object.freeze(g); // 冻结对象，对象中的属性不能修改
    Object.defineProperty(this, "data", {
      get() {
        return g;
      },
      set() {
        throw new Error("data属性是只读的，不能重新赋值");
      },
      configurable: false,
    });
    let internalChooseValue = 0;
    Object.defineProperty(this, "choose", {
      get() {
        return internalChooseValue;
      },
      set(val) {
        if (typeof val !== "number") {
          throw new Error("choose属性必须是数字");
        }
        const temp = ~~val;
        if (temp !== val) {
          throw new Error("choose属性必须是整数");
        }
        if (val < 0) {
          throw new Error("choose属性必须大于等于0");
        }
        internalChooseValue = val;
      },
      configurable: false,
    });

    Object.defineProperty(this, "totalPrice", {
      get() {
        return this.choose * this.data.price;
      },
    });

    this.a = 1;
    // Object.freeze(this); // 冻结自身，让外部不能修改UiGoods创建的对象
    Object.seal(this); // 密封：允许修改属性值：密封后的对象，其现有属性值可修改（前提是属性本身可写，即writable: true）
  }
}

const g = new UIGoods(aGoods);
// g.data.price = 100;
g.abc = 123;
console.log(g, g.data);
g.choose = 2;
console.log(g.totalPrice);
